package com.dolawing.phonecallapp.listenphonecall;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
import android.telecom.TelecomManager;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.RemoteViews;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;

import com.android.internal.telephony.ITelephony;

import com.dolawing.phonecallapp.MainActivity;
import com.dolawing.phonecallapp.R;
import com.dolawing.phonecallapp.blacknumber.db.BlackNumberDao;
import com.dolawing.phonecallapp.keepAliveService.IKeepAliveService;
import com.dolawing.phonecallapp.keepAliveService.RemoteService;
import com.dolawing.phonecallapp.keepAliveUi.KeepManager;
import com.dolawing.phonecallapp.phoneLog.CallDetails;
import com.dolawing.phonecallapp.phoneLog.PhoneCallUtils;
import com.google.gson.Gson;


import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
@SuppressWarnings("deprecation")
public class CallListenerService extends Service {

    public static Handler isFlotViewHandler;

    private TextView tvCallNumber;
    private Button btnOpenApp;

    private WindowManager windowManager;
    private WindowManager.LayoutParams params;

    private PhoneStateListener phoneStateListener;
    private TelephonyManager telephonyManager;

    private String callNumber;
    private boolean hasShown;
    private boolean isCallingIn;

    private boolean isFlotView = false;

    private long endringTimesTimeToCallNotLog; // | 去电未接的响铃时间
    private long callTimesSaveToCallNotLog; // | 去电的开始时间

    private long ringToTimesTime; // 去电响铃时间
    private long callStartTimeRingToTimesTime; //  去电开始铃时间
    private long callEndTimeRingToTimesTime; //  去电结束铃时间
    private long callTimeTo; //  去电开始铃时间
//    private int notifyId = 111;

    private MyBinder binder;
    private MyConn conn;
    private IKeepAliveService iKeepAliveService;
    private NotificationCompat.Builder builder;
    private int notifyId =2;
    private int count = 100;  //从100开始，与RemoteService区分
    private String netWorkState = "";  //从100开始，与RemoteService区分
    private String serviceFlot = "";  //从100开始，与RemoteService区分

    private boolean cycleFlag = true;  //循环标示


    RemoteViews remoteViews;


    private Context mContext;

    /**
     * 初始化来电状态监听器
     */
    boolean callFrom = false;
    boolean callTo = false;

    boolean notCall = false;

    long nowTime;

    private long ringTimesTime; // 来电响铃时间
    private long startTimesTime; // 开始来电响铃时间
    private long endTimesTime; // 结束响铃时间
    private String callStartTime = "0"; // 来电通话时间
    private String callEndTime; // 来电通话结束时间


    private long ringTimesTimeNotCallLog; // | 来电未接的响铃时间
    private long startringTimesTimeNotCallLog; // | 开始来电未接的响铃时间
    private long endringTimesTimeNotCallLog; // | 结束来电未接的响铃时间

    private long ringTimesTimeRefuseCallLog; // | 拒绝的响铃时间
    private long startringTimesRefuseCallLog; // | 拒绝的开始响铃时间
    private long endringTimesRefuseCallLog; // | 拒绝的结束响铃时间
    private long callTimesRefuseCallLog; // | 拒绝的开始时间

    private long callTime; // 来电时间

    private Handler Calling; // 接听挂断

    private Handler toCallHandler; // 去电对象获取器

    public Handler showHandler;

    public Handler toCallLogHanlder; // 去电接听后挂断

    public int readCount = 0; // 应用角标


    private boolean isNowNetWork = true;
    private String CHANNEL_ID = "com.dolawing.phonecall.alarm.AppService";
    private String CHANNEL_NAME = "dolawing";
    private NotificationManager notificationManager;

    private String tag;
    private String tag2;
    //************************************************
    private View phoneCallView;
    private BlackNumberDao blackNumberDao;
    @Override
    public void onCreate() {
        super.onCreate();
        mContext = this;
        mHandler = new Handler(Looper.getMainLooper());
        binder = new MyBinder();
        conn = new MyConn();
        startTo();
        //绑定服务
        boolean flag = this.bindService(new Intent(CallListenerService.this, RemoteService.class),
                conn, Context.BIND_AUTO_CREATE);
        if (flag){
            Message msg = Message.obtain();
            handler.sendMessage(msg);
        }
        new Thread(new Runnable(){
            @Override
            public void run() {
                try {
                    while(cycleFlag){
                        try {
                            count = (count+1)%36000;
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }


                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();


        initPhoneStateListener();


        initPhoneCallView(); // 初始化控件
    }


    //    =================================电状态监听器==================================================
    /**
     * 初始化来电状态监听器
     */
    private void initPhoneStateListener() {

        phoneStateListener = new PhoneStateListener() {
            @SuppressLint("SwitchIntDef")
            @Override
            public void onCallStateChanged(int state, String incomingNumber) {
                super.onCallStateChanged(state, incomingNumber);
                callNumber = incomingNumber;
                switch (state) {
                    case TelephonyManager.CALL_STATE_IDLE: // 待机，即无电话时，挂断时触发
                        if(callFrom){
                            Log.e("TAG", "**********************来电电话挂断!!!!*******************");
                            dismiss();
                            Calling = new Handler(Looper.getMainLooper()){
                                @Override
                                public void handleMessage(@NonNull Message msg) {

                                    String printLastCallLog = msg.getData().getString("printLastCallLog");
                                    CallDetails callDetails = new Gson().fromJson(printLastCallLog, CallDetails.class);
//

                                    switch (callDetails.getCallType()){
                                        case "来电":
                                            Log.e("call", "=========来电接听挂断=====");

                                            callFrom = false;
                                            break;
                                        case "未接":
                                            System.out.println("来电未接");

                                            callFrom = false;
                                            break;

                                        case "拒绝":
                                            nowTime = 0;
                                            System.out.println("拒绝接听");

                                            callFrom = false;
                                            break;
                                    }
                                }
                            };
                            printLastCallLog(Calling);

//                            Log.d("TAG", "********************** 待机，即无电话时，挂断时触发!!!!*******************");
                            Log.e("TAG", "********************** 待机，即无电话时"+isFlotView+"!!!!*******************");
                            if(isFlotView){
                            }
                            return;
                        }
                        if(callTo) {
                            dismiss();
                            Log.e("TAG", "**********************去电电话挂断!!!!*******************");
                            toCallLogHanlder = new Handler(Looper.getMainLooper()){
                                @Override
                                public void handleMessage(@NonNull Message msg) {
                                    String printLastCallLog = msg.getData().getString("printLastCallLog");
                                    CallDetails callDetails = new Gson().fromJson(printLastCallLog, CallDetails.class);

                                    if(callDetails.getCallDuration().equals("0") || callDetails.getCallDuration() == null){
                                        System.out.println("去电没有录音" + callDetails);

                                    }else {
                                        System.out.println("去电有录音" + callDetails);
                                    }
                                    callFrom = false;
                                    if(isFlotView){
                                    }
                                }
                            };

                            printLastCallLog(toCallLogHanlder);
                            return;
                        }


                        break;
                    case TelephonyManager.CALL_STATE_RINGING: // 响铃，来电时触发
                        Log.e("TAG", "**********************监测到电话呼入!!!!*******************");
                        Log.e("TAG", "**********************当前弹窗状态"+hasShown+"!!!!*******************");

                        updateUI();
                        show();
                        callFrom = true;

                        break;

                    case TelephonyManager.CALL_STATE_OFFHOOK: // 摘机，接听或拨出电话时触发
                        Log.e("TAG", "**********************callFrom"+callFrom+"!!!!*******************");
                        if(callFrom){
                            Log.e("TAG", "**********************来电电话接听!!!!*******************");
                            notCall = true;

                            updateUI();
                            show();
                            return;
                        }
                        callTo = true;
                        Log.e("TAG", "**********************去电电话接听!!!!*******************");
                        Log.e("TAG", "**********************去电手机号"+callNumber+"*******************");
                        Log.e("TAG", "**********************去电手机号111111111111111111111*******************");

                        updateUI();
                        show();

                        break;

                    default:
                        break;

                }
            }
        };

        // 设置来电监听器
        telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
        if (telephonyManager != null) {
            telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
        }
    }
    //    =================================电状态监听器==================================================


    //    =================================双线程保活==================================================
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("在LocalService服务...","onStartCommand方法执行");
        this.bindService(new Intent(CallListenerService.this, RemoteService.class),
                conn, Context.BIND_AUTO_CREATE);

        return START_STICKY;
    }

    private void setNotification(int number, String text){
        remoteViews.setTextViewText(number, text);
        builder.setContent(remoteViews);
        builder.setCustomBigContentView(remoteViews);
        startForeground(notifyId, builder.build());
    }

    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }
    private Handler handler = new Handler(Looper.getMainLooper()){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            new Thread(new Runnable(){
                @Override
                public void run() {
                    try {
                        while(cycleFlag){
                            Calendar calendar = Calendar.getInstance();
                            int hour = calendar.get(Calendar.HOUR_OF_DAY);
                            int min = calendar.get(Calendar.MINUTE);
                            int sec = calendar.get(Calendar.SECOND);
                            String timestamps = ""+hour + "时" + min+"分" + sec +"秒";//记录时间
                            try {
                                Thread.sleep(1000);
                                builder.setContentText("Running..."+timestamps+" "+iKeepAliveService.getServiceName()+"中,count="+iKeepAliveService.getCount());
                                startForeground(notifyId, builder.build());
//                                Log.i("在LocalService服务中.....","LocalService与"+iKeepAliveService.getServiceName()+"建立链接");
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    };

    private class MyBinder extends IKeepAliveService.Stub {
        @Override
        public String getServiceName() throws RemoteException {
            return CallListenerService.class.getSimpleName();
        }

        @Override
        public int getCount() throws RemoteException {
            return count;
        }
    }

    private class MyConn implements ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iKeepAliveService =IKeepAliveService.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            cycleFlag = false;
            Intent intent = new Intent(CallListenerService.this, RemoteService.class);
            if (Build.VERSION.SDK_INT >= 26) {
                //适配8.0机制
                CallListenerService.this.startForegroundService(intent);
            } else {
                CallListenerService.this.startService(intent);
            }
            //绑定远程服务
            CallListenerService.this.bindService(new Intent(CallListenerService.this, RemoteService.class), conn, Context.BIND_AUTO_CREATE);

        }
    }
    private void startTo() {
        String CHANNEL_ID = "com.dolawing.lawork.reciver.listenphonecall.CallListenerService";
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        NotificationChannel Channel = null;
        Notification notification = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            Channel = new NotificationChannel(CHANNEL_ID, "Local Service", NotificationManager.IMPORTANCE_LOW);
            Channel.enableLights(true);
            Channel.setLightColor(Color.RED);
            Channel.setShowBadge(true);
            Channel.setDescription("LocalService");
            Channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC); //设置锁屏可见 VISIBILITY_PUBLIC=可见
            manager.createNotificationChannel(Channel);
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String nowTimes = sdf.format(new Date());
        builder = new NotificationCompat.Builder(CallListenerService.this, CHANNEL_ID)
                .setContentTitle("Local Service,启动:"+nowTimes)//标题
                .setContentText("Running...")//内容
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.drawable.ic_launcher_background);//小图标一定需要设置,否则会报错(如果不设置它启动服务前台化不会报错,但是你会发现这个通知不会启动),如果是普通通知,不设置必然报错
//                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))

        notification = builder.build();

        //让通知显示出来 第一个参数是id，要保证每个通知所指定的id各不相同 第二个参数是Notification对象
        manager.notify(notifyId, notification);
    }
//    =================================双线程保活==================================================


    private Handler mHandler = null; // 获取日志的处理器
    private void  printLastCallLog(Handler handler){
        mHandler = new Handler();
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                CallDetails callDetail = PhoneCallUtils.getLastOneCallDetails(getApplicationContext());
                // 通知发送消息
                Message message = handler.obtainMessage();
                Bundle bundle = new Bundle();
                String saveBlackDetailJson = new Gson().toJson(callDetail);
                bundle.putString("printLastCallLog", saveBlackDetailJson);
                message.setData(bundle);
                handler.sendMessage(message); // 通知完成
            }
        },1000);
    };

    //    ==================================弹窗的初始参数=======================================
    private void initPhoneCallView() {
        windowManager = (WindowManager) getApplicationContext()
                .getSystemService(Context.WINDOW_SERVICE);
        int width = windowManager.getDefaultDisplay().getWidth();
        int height = windowManager.getDefaultDisplay().getHeight();

        params = new WindowManager.LayoutParams();
        params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
        params.width = width;
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        params.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;

        // 设置图片格式，效果为背景透明
        params.format = PixelFormat.TRANSLUCENT;
        // 设置 Window flag 为系统级弹框 | 覆盖表层
        params.type = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY :
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
//        params.type = WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
        // 不可聚集（不响应返回键）| 全屏
        params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_FULLSCREEN
                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
        // API 19 以上则还可以开启透明状态栏与导航栏
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            params.flags = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                    | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION
                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_FULLSCREEN
                    | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
        }

        FrameLayout interceptorLayout = new FrameLayout(this) {

            @Override
            public boolean dispatchKeyEvent(KeyEvent event) {

                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {

                        return true;
                    }
                }

                return super.dispatchKeyEvent(event);
            }
        };

        phoneCallView = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE))
                .inflate(R.layout.view_phone_call, interceptorLayout);
        tvCallNumber = phoneCallView.findViewById(R.id.tv_call_number);
        btnOpenApp = phoneCallView.findViewById(R.id.btn_open_app);
        btnOpenApp.setOnClickListener(v -> {
            Intent intent = new Intent(getApplicationContext(), MainActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            CallListenerService.this.startActivity(intent);
        });
    }

    /**
     * 显示顶级弹框展示通话信息
     */
    private void show() {
        KeyguardManager mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
        boolean flag = mKeyguardManager.inKeyguardRestrictedInputMode();
        if (flag) {
            Log.i("手机状态","锁屏中。。。。。");
            Toast.makeText(this,"锁屏中。。。。。",Toast.LENGTH_LONG).show();
            PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
            @SuppressLint("InvalidWakeLockTag")
            PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP |
                    PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "bright");
            wl.acquire();
            wl.release();
            //启动 弹窗 Activity
            Handler mHandler = new Handler(getMainLooper());
            MyRunnable runnable = new MyRunnable(this);
            mHandler.postDelayed(runnable,3000);
        }else{
            if (!hasShown) {
                windowManager.addView(phoneCallView, params);
                hasShown = true;
            }
        }
    }
    class MyRunnable implements Runnable{
        private Context mCx;
        public MyRunnable(Context context){
            mCx = context;
        }
        @Override
        public void run() {
            Log.i("Thread","2秒执行结束...");
            KeepManager.getInstance().startKeep(mCx);
        }
    }
    /**
     * 取消显示
     */
    private void dismiss() {
        //关闭 弹窗 Activity
        KeepManager.getInstance().finishKeep();
        if (hasShown) {
            windowManager.removeView(phoneCallView);
            isCallingIn = false;
            hasShown = false;
        }
    }

    private void updateUI() {
        tvCallNumber.setText(formatPhoneNumber(callNumber));

        int callTypeDrawable = isCallingIn ? R.drawable.ic_phone_call_in : R.drawable.ic_phone_call_out;
        tvCallNumber.setCompoundDrawablesWithIntrinsicBounds(null, null,
                getResources().getDrawable(callTypeDrawable), null);
    }

    public static String formatPhoneNumber(String phoneNum) {
        if (!TextUtils.isEmpty(phoneNum) && phoneNum.length() == 11) {
            return phoneNum.substring(0, 3) + "-"
                    + phoneNum.substring(3, 7) + "-"
                    + phoneNum.substring(7);
        }
        return phoneNum;
    }


    @Override
    public void onDestroy() {
        unbindService(conn); //解绑
        cycleFlag = false;
        super.onDestroy();

//        timer.cancel();
//        releaseWakeLock(getApplicationContext());// 释放锁
        telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
        //销毁
//        stopForeground(true);
        Log.d("cxa", "CallListenerService---->onDestroy，前台service被杀死");
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//            getApplicationContext().startForegroundService(new Intent(getApplicationContext(), CallListenerService.class));
//        } else {
//            getApplicationContext().startService(new Intent(getApplicationContext(), CallListenerService.class));
//        }

    }

    //挂断电话 2
    private void endCall2(String phone) {
        boolean flag = false;//判断是否拦截成功
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            TelecomManager manager = (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
            if (manager != null) {
                if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ANSWER_PHONE_CALLS) != PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(getApplicationContext(),"没有权限，拦截失败！",Toast.LENGTH_SHORT).show();
                }
                flag = manager.endCall();
            }
        }else {
            //ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));
            try {
                //获取类
                @SuppressLint("PrivateApi")
                Class<?> serviceManager = Class.forName("android.os.ServiceManager");
                //获取方法
                Method getService = serviceManager.getMethod("getService", String.class);
                //使用方法
                IBinder invoke = (IBinder) getService.invoke(null, Context.TELEPHONY_SERVICE);
                ITelephony iTelephony = ITelephony.Stub.asInterface(invoke);
                assert iTelephony != null;
//                if("10086".equals(phone)){
//                    flag = iTelephony.endCall();//挂断电话
//                    Toast.makeText(getApplicationContext(),"方法二：28版本以下：10086被拦截！",Toast.LENGTH_SHORT).show();
//                }
                flag = iTelephony.endCall();//挂断电话
            } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | RemoteException e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 1. 点亮屏幕，防止屏幕息屏
     */
    PowerManager.WakeLock mWakeLock;
    @SuppressLint("InvalidWakeLockTag")
    public void getWakeLock(Context ctx) {
        if (mWakeLock == null) {
            // 应用程序获取PowerManager服务
            // PowerManager是系统服务，所以它的生命周期不是应用程序所能控制的；应用程序只能通过系统，向系统请求获取PowerManager服务，然后系统把这个服务的应用给我们
            PowerManager pMgr = (PowerManager) ctx
                    .getSystemService(Context.POWER_SERVICE);
            mWakeLock = pMgr.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "wakeLock");
        }
        if (mWakeLock != null && !mWakeLock.isHeld()) {
            mWakeLock.acquire();
        }
    }

    /**
     * 2. 释放常亮锁
     *
     * @param ctx
     */
    public void releaseWakeLock(Context ctx) {
        try {
            if (mWakeLock != null && mWakeLock.isHeld()) {
                mWakeLock.release();
            }
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }




}